#include <QDateTime>

#include "ivsmainwindow.h"
#include "ui_ivsmainwindow.h"
#include <QInputDialog>
#include <QMessageBox>

void selfDestroy();

IVSMainWindow::IVSMainWindow(IVSModel* _model, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::IVSMainWindow)
{
    ui->setupUi(this);
    ivsModel = _model;
    initView();
    ui->pushButtonShowLog->setText("Hide log");
    ui->pushButtonRun->setText("Run");
    connect(ui->pushButtonShowLog, SIGNAL(toggled(bool)), this, SLOT(setShowLogButton(bool)));
    connect(ui->pushButtonRun, SIGNAL(clicked()), this, SLOT(toggleRunButtonText()));


    connect(ui->comboBoxVideoSource, SIGNAL(currentIndexChanged(QString)), ivsModel, SLOT(setCurrentVideoSource(QString)));
    connect(ui->comboBoxVerboseLevel, SIGNAL(currentIndexChanged(QString)), ivsModel, SLOT(setVerboseLevel(QString)));
    connect(ui->comboBoxFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentFuntion()));
    connect(this, SIGNAL(currentFunction_changed(IVS::eFunctions)), ivsModel, SLOT(setCurrentFunction(IVS::eFunctions)));
    bUpdate = false;
    appendLog(" Start", Qt::gray);
#ifdef IVS_DEBUG
    ui->comboBoxFunction->setCurrentIndex(5);
    emit currentFunction_changed(IVS::Restricted_area_survuillance);
    updateTableFunction();
    ui->comboBoxVideoSource->setCurrentIndex(8);
#endif
}

IVSMainWindow::~IVSMainWindow()
{
    delete ui;
}


void IVSMainWindow::initView()
{
    initComboFunction();
    initTableFunction();
    initComboVideoSource();
    initTableVideoSource();
    initComboVerboseLevel();
    initTextBrowserLog();
    status("Ready");
}

void IVSMainWindow::initComboFunction()
{
    functionList << tr("Video player")
                 << tr("Intruders detection")
                 << tr("Restricted area survuillance")
                 << tr("Fence survuillance")
                 << tr("People counting")
                 << tr("People tracking")
                 << tr("Theft detection")
                 << tr("Object left behide detection")
                 << tr("Camera checks");
    ui->comboBoxFunction->addItems(functionList);
    //    ui->tableWidgetFunction->hide();
    //    ui->tableWidgetVideoSource->hide();
}

void IVSMainWindow::initTableFunction()
{
    setupTableFunction();
    connect(ui->tableWidgetFunction, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(tableFunctionItemChanged(QTableWidgetItem*)));
}

void IVSMainWindow::initComboVideoSource()
{
    ui->comboBoxVideoSource->addItems(ivsModel->ListVideoSourceName());

    if(ivsModel->CurrentVideoSourceIndex() != -1)
    {
        ui->comboBoxVideoSource->setCurrentIndex(ivsModel->CurrentVideoSourceIndex());
    }else{
        //TODO: set current video source
    }

    if(ui->comboBoxVideoSource->currentIndex() == -1)
        ui->toolButtonRemoveVideoSource->setDisabled(true);
}

void IVSMainWindow::initTableVideoSource()
{
    ui->tableWidgetVideoSource->setColumnCount(2);
    ui->tableWidgetVideoSource->setRowCount(3);
    ui->tableWidgetVideoSource->setHorizontalHeaderLabels(QStringList()
                                                          << tr("Attribute")
                                                          << tr("Value"));

    ui->tableWidgetVideoSource->setItem(0,0, new QTableWidgetItem(tr("Source type: ")));
    ui->tableWidgetVideoSource->setItem(1,0, new QTableWidgetItem(tr("Source: ")));
    ui->tableWidgetVideoSource->setItem(2,0, new QTableWidgetItem(tr("ROI: ")));
    ui->tableWidgetVideoSource->setItem(0,1, new QTableWidgetItem(tr("")));
    ui->tableWidgetVideoSource->setItem(1,1, new QTableWidgetItem(tr("")));
    ui->tableWidgetVideoSource->setItem(2,1, new QTableWidgetItem(tr("")));
    ui->tableWidgetVideoSource->resizeRowsToContents();
    ui->tableWidgetVideoSource->setColumnWidth(0, 80);
    ui->tableWidgetVideoSource->setColumnWidth(1, 234);
    updateTableVideoSource();

    ui->tableWidgetVideoSource->item(0,1)->setToolTip(tr("0: LocalFile\n1: Stream\n2: LocalCAM\n-1: InvalidVideoSource"));
    ui->tableWidgetVideoSource->item(2,1)->setToolTip(tr("To set ROI: Focus on video window, and press R.\n Left click: set point.\n Right click: finish"));
    connect(ui->tableWidgetVideoSource, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(tableVideoSourceItemChanged(QTableWidgetItem* )));
}

void IVSMainWindow::initComboVerboseLevel()
{
    ui->comboBoxVerboseLevel->addItems(QStringList()
                                       << "0"
                                       << "1"
                                       << "2"
                                       << "3");
    ui->comboBoxVerboseLevel->setCurrentIndex(ivsModel->VerboseLevel());
}

void IVSMainWindow::initTextBrowserLog()
{
    //    ui->textBrowserLog->setSource(QUrl::fromLocalFile(LOG_FILE_NAME));
}

void IVSMainWindow::clearTableFunction()
{
    ui->tableWidgetFunction->clear();
}

void IVSMainWindow::clearTableVideoSource()
{
    ui->tableWidgetVideoSource->clear();
}

void IVSMainWindow::clearComboVideoSource()
{
    ui->comboBoxVideoSource->clear();
}

IVS::eFunctions IVSMainWindow::getCurrentFunction()
{
    if(ui->comboBoxFunction->currentText().compare(functionList.at(0)) == 0)
        return IVS::Video_player;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(1)) == 0)
        return IVS::Intruders_detection;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(2)) == 0)
        return IVS::Restricted_area_survuillance;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(3)) == 0)
        return IVS::Fence_survuillance;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(4)) == 0)
        return IVS::People_counting;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(5)) == 0)
        return IVS::People_tracking;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(6)) == 0)
        return IVS::Theft_detection;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(7)) == 0)
        return IVS::Object_left_behide_detection;
    else if(ui->comboBoxFunction->currentText().compare(functionList.at(8)) == 0)
        return IVS::Camera_checks;
    else
        return IVS::Video_player;
}

QString IVSMainWindow::getCurrentVideoSourceName()
{
    return ui->comboBoxVideoSource->currentText();
}

QString IVSMainWindow::getLog()
{
    return ui->textBrowserLog->toHtml();
}

void IVSMainWindow::appendLog(QString log, QColor color)
{
    QString aLog;
    aLog.append(QDateTime::currentDateTime().toString(Qt::DefaultLocaleShortDate) + "> ");
    aLog.append(log);
    ui->textBrowserLog->setTextColor(color);
    ui->textBrowserLog->append(aLog);
}

void IVSMainWindow::setShowLogButton(bool isShowLog)
{
    if(isShowLog)
        ui->pushButtonShowLog->setText("Hide log");
    else
        ui->pushButtonShowLog->setText("Show log");
}

void IVSMainWindow::toggleRunButtonText()
{
    if(ui->pushButtonRun->text().compare("Run") == 0){
        ui->pushButtonRun->setText("Stop");
        appendLog("Run: " + ui->comboBoxFunction->currentText() +
                  " @ " + ui->comboBoxVideoSource->currentText());
        status(ui->comboBoxFunction->currentText() + " :Running");
    }
    else{
        ui->pushButtonRun->setText("Run");
        appendLog("Stop: " + ui->comboBoxFunction->currentText() +
                  " @ " + ui->comboBoxVideoSource->currentText());
        status();
    }
    emit clickedPushButtunRun();
}

void IVSMainWindow::status(QString textStatus)
{
    ui->statusBar->showMessage(textStatus);
}

void IVSMainWindow::status(QString textStatus, QColor color)
{
    status(textStatus);
    appendLog(textStatus, color);
}

void IVSMainWindow::clearStatus()
{
    ui->statusBar->clearMessage();
}

void IVSMainWindow::on_toolButtonAddVideoSource_clicked()
{
    bool ok;
    QString newVideoSourceName = QInputDialog::getText(this, tr("New video source name"),
                                                       tr("New video source name:"), QLineEdit::Normal,
                                                       "", &ok);
    if (ok && !newVideoSourceName.isEmpty())
        ivsModel->addNewVideoSource(newVideoSourceName);
}

void IVSMainWindow::updateVideoSource()
{
    updateComboVideoSource();
    updateTableVideoSource();
}

void IVSMainWindow::updateComboVideoSource()
{
    bUpdate = true;
    if(ui->comboBoxVideoSource->count() == ivsModel->ListVideoSourceName().length())
        return;
    clearComboVideoSource();
    ui->comboBoxVideoSource->addItems(ivsModel->ListVideoSourceName());

    //    if(ivsModel->CurrentVideoSourceIndex() != -1)
    //    {
    //        ui->comboBoxVideoSource->setCurrentIndex(ivsModel->CurrentVideoSourceIndex());
    //    }

    if(ui->comboBoxVideoSource->currentIndex() == -1)
        ui->toolButtonRemoveVideoSource->setDisabled(true);
    else
        ui->toolButtonRemoveVideoSource->setDisabled(false);
    bUpdate = false;
}

void IVSMainWindow::updateTableVideoSource()
{
    bUpdate = true;
    IVS::VideoSource vs = ivsModel->getCurrentVideoSource();
    ui->tableWidgetVideoSource->item(0,1)->setText(algHelper::cvtEVideoSourceType2String(vs.sourceType));
    ui->tableWidgetVideoSource->item(1,1)->setText(vs.source);
    ui->tableWidgetVideoSource->item(2,1)->setText(algHelper::cvtPointList2Text(vs.ROI));

    bUpdate = false;
}

void IVSMainWindow::tableFunctionItemChanged(QTableWidgetItem *changedItem)
{
    qWarning(qPrintable(QString("bUpdate: %1").arg(
                            bUpdate?"true":"false")));
    if(bUpdate)
        return;
    bUpdate = true;
    if(changedItem->column() == 1){
        switch(ivsModel->CurrentFunction()){
        case IVS::Video_player:
            switch(changedItem->row()){
            case 0:
                ivsModel->setVideoPlayerSettings_EnableROI(
                            changedItem->text().compare("true",Qt::CaseInsensitive) == 0);
                break;
            }
            break;
        case IVS::Intruders_detection:
            switch(changedItem->row()){
            case 0:
                ivsModel->setIntrudersDetectionSettings_NoFrameToInitBG(
                            changedItem->text().toInt());
                break;
            case 1:
                ivsModel->setIntrudersDetectionSettings_Alpha(
                            changedItem->text().toFloat());
                break;
            case 2:
                ivsModel->setIntrudersDetectionSettings_StateChangeDelay(
                            changedItem->text().toInt());
                break;
            case 3:
                ivsModel->setIntrudersDetectionSettings_BoundRectAreaMin(
                            changedItem->text().toUInt());
                break;
            case 4:
                ivsModel->setIntrudersDetectionSettings_BoundRectAreaMax(
                            changedItem->text().toUInt());
                break;
            case 5:
                ivsModel->setIntrudersDetectionSettings_NoBin(
                            changedItem->text().toInt());
                break;
            }
            break;
        case IVS::Restricted_area_survuillance:
            switch(changedItem->row()){
            case 0:
                ivsModel->setRestrictedAreaSurvuillanceSettings_NoFrameToInitBG(
                            changedItem->text().toInt());
                break;
            case 1:
                ivsModel->setRestrictedAreaSurvuillanceSettings_Alpha(
                            changedItem->text().toFloat());
                break;
            case 2:
                ivsModel->setRestrictedAreaSurvuillanceSettings_StateChangeDelay(
                            changedItem->text().toInt());
                break;
            case 3:
                ivsModel->setRestrictedAreaSurvuillanceSettings_BoundRectAreaMin(
                            changedItem->text().toUInt());
                break;
            case 4:
                ivsModel->setRestrictedAreaSurvuillanceSettings_BoundRectAreaMax(
                            changedItem->text().toUInt());
                break;
            case 5:
                ivsModel->setRestrictedAreaSurvuillanceSettings_NoBin(
                            changedItem->text().toInt());
                break;
            }
            break;
        case IVS::Fence_survuillance:
            switch(changedItem->row()){
            case 0:
                break;
            }
            break;
        case IVS::People_counting:
            switch(changedItem->row()){
            case 0:
                break;
            }
            break;
        case IVS::People_tracking:
            switch(changedItem->row()){
            case 0:
                break;
            }
            break;
        case IVS::Theft_detection:
            switch(changedItem->row()){
            case 0:
                break;
            }
            break;
        case IVS::Object_left_behide_detection:
            switch(changedItem->row()){
            case 0:
                break;
            }
            break;
        case IVS::Camera_checks:
            switch(changedItem->row()){
            case 0:
                ivsModel->setCameraChecksSettings_NoFrameToInitBG(
                            changedItem->text().toInt());
                break;
            case 1:
                ivsModel->setCameraChecksSettings_Apla(
                            changedItem->text().toFloat());
                break;
            case 2:
                ivsModel->setCameraChecksSettings_StateChangeDelay(
                            changedItem->text().toInt());
                break;
            case 3:
                ivsModel->setCameraChecksSettings_BeCoveredThreshold(
                            changedItem->text().toInt());
                break;
            case 4:
                ivsModel->setCameraChecksSettings_VideoPlaySpeedBoost(
                            changedItem->text().toInt());
                break;
            }
            break;
        }

        bUpdate = false;
    }
}

void IVSMainWindow::tableVideoSourceItemChanged(QTableWidgetItem* changedItem)
{
    if(bUpdate)
        return;
    bUpdate = true;
    if(changedItem->column() == 1){
        switch(changedItem->row()){
        case 0:
            ivsModel->setSourceType(algHelper::cvtIndex2eVideoSourceType(changedItem->text().toInt()));
            ui->tableWidgetVideoSource->item(0,1)->setText(algHelper::cvtEVideoSourceType2String(
                                                               algHelper::cvtIndex2eVideoSourceType(
                                                                   changedItem->text().toInt())));
            break;
        case 1:
            ivsModel->setSource(changedItem->text());
            break;
        case 2:
            ui->tableWidgetVideoSource->item(2,1)->setText(algHelper::cvtPointList2Text(
                                                               ivsModel->getCurrentVideoSource().ROI));
            break;
        }
    }

    bUpdate = false;
}

void IVSMainWindow::closeEvent(QCloseEvent *event)
{
    appendLog(" Exit", Qt::gray);
    ui->textBrowserLog->append(QString(" "));
    ivsModel->saveAllSettings();
    ivsModel->log(this->getLog());
    event->accept();

    ::selfDestroy();
}

void IVSMainWindow::setupTableFunction()
{
    switch(ivsModel->CurrentFunction()){
    case IVS::Video_player:
        createTableFunctionHeader(QStringList()
                                  << "Enable ROI");
        setTableFunctionValue(0,ivsModel->VideoPlayerSettings().isEnableROI? "true": "false");
        break;
    case IVS::Intruders_detection:
        createTableFunctionHeader(QStringList()
                                  << "Init BG(#frame)"
                                  << "Alpha(0..1)"
                                  << "State change delay(#frame)"
                                  << "Bound rect area(min)"
                                  << "Bound rect area(max)"
                                  << "Number of bin"
                                  );
        setTableFunctionValue(0,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().noFrameToInitBackground));
        setTableFunctionValue(1,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().alpha));
        setTableFunctionValue(2,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().stateChangeDelay));
        setTableFunctionValue(3,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().bnRectArea_min));
        setTableFunctionValue(4,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().bnRectArea_max));
        setTableFunctionValue(5,
                              QString("%1").arg(
                                  ivsModel->IntrudersDetectionSettings().noBin));
        break;
    case IVS::Restricted_area_survuillance:
        createTableFunctionHeader(QStringList()
                                  << "Init BG(#frame)"
                                  << "Alpha(0..1)"
                                  << "State change delay(#frame)"
                                  << "Bound rect area(min)"
                                  << "Bound rect area(max)"
                                  << "Number of bin"
                                  );
        setTableFunctionValue(0,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().noFrameToInitBackground));
        setTableFunctionValue(1,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().alpha));
        setTableFunctionValue(2,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().stateChangeDelay));
        setTableFunctionValue(3,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().bnRectArea_min));
        setTableFunctionValue(4,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().bnRectArea_max));
        setTableFunctionValue(5,
                              QString("%1").arg(
                                  ivsModel->RestrictedAreaSurvuillanceSettings().noBin));
        break;
    case IVS::Fence_survuillance:

        break;
    case IVS::People_counting:

        break;
    case IVS::People_tracking:

        break;
    case IVS::Theft_detection:

        break;
    case IVS::Object_left_behide_detection:

        break;
    case IVS::Camera_checks:
        createTableFunctionHeader(QStringList()
                                  << "Init BG(#frame)"
                                  << "Alpha(0..1)"
                                  << "State change delay(#frame)"
                                  << "Be covered threshold(illumination)"
                                  << "Video play speed boost(fps)"
                                  );
        setTableFunctionValue(0,
                              QString("%1").arg(
                                  ivsModel->CameraChecksSettings().noFrameToInitBackground));
        setTableFunctionValue(1,
                              QString("%1").arg(
                                  ivsModel->CameraChecksSettings().alpha));
        setTableFunctionValue(2,
                              QString("%1").arg(
                                  ivsModel->CameraChecksSettings().stateChangeDelay));
        setTableFunctionValue(3,
                              QString("%1").arg(
                                  ivsModel->CameraChecksSettings().beCoveredThreshold));
        setTableFunctionValue(4,
                              QString("%1").arg(
                                  ivsModel->CameraChecksSettings().videoPlaySpeedBoost));
        break;
    }
    bUpdate = false;
}

void IVSMainWindow::createTableFunctionHeader(QStringList listRowHeader)
{
    ui->tableWidgetFunction->clear();

    ui->tableWidgetFunction->setColumnCount(2);
    if(listRowHeader.length() > 3)
        ui->tableWidgetFunction->setRowCount(listRowHeader.length());
    else
        ui->tableWidgetFunction->setRowCount(3);
    ui->tableWidgetFunction->setHorizontalHeaderLabels(QStringList()
                                                       << tr("Attribute")
                                                       << tr("Value"));
    ui->tableWidgetFunction->setColumnWidth(0, 80);
    ui->tableWidgetFunction->setColumnWidth(1, 234);

    for(int i = 0; i < listRowHeader.length(); i++){
        ui->tableWidgetFunction->setItem(i,0, new QTableWidgetItem(listRowHeader.at(i)));
        ui->tableWidgetFunction->setItem(i,1, new QTableWidgetItem(tr("")));
    }
    ui->tableWidgetFunction->resizeRowsToContents();
    ui->tableWidgetFunction->resizeColumnsToContents();
    ui->tableWidgetFunction->setColumnWidth(1,300 -
                                            ui->tableWidgetFunction->columnWidth(0));
}

void IVSMainWindow::setCurrentFuntion()
{
    emit currentFunction_changed(getCurrentFunction());
}

void IVSMainWindow::updateTableFunction()
{
    setupTableFunction();
}

void IVSMainWindow::setTableFunctionValue(int row, QString text)
{
    ui->tableWidgetFunction->item(row, 1)->setText(text);
}
void IVSMainWindow::updateROI(bool isComplete)
{
    qWarning("MainWindows: update ROI");
    ui->tableWidgetVideoSource->item(2,1)->setText(algHelper::cvtPointList2Text(
                                                       ivsModel->CurrentVideoSource().ROI));
    qWarning("MainWindows: update ROI - done");
}
